<?php

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Description of BUIBase
 *
 * @author ID59C
 */
abstract class BUIBase extends CComponent implements BUIObj {

    const BOOTSTRAPSTYLE = "bootstrap";
    const TRANSITVARIABLE_STRING = 'string';
    const TRANSITVARIABLE_SCOPETYPE = 'ScopeVariable';
    const LinkType_AjaxLink = "ajaxLink";
    const LinkType_AjaxButton = "ajaxButton";
    const LinkType_AjaxSubmitButton = "ajaxSubmitButton";

    protected $views = null;
    protected $ajaxViews = null;
    protected $layoutView = null;
    protected $count = 0;

    public function __construct() {
        $this->onRegisterMenu = array($this, 'registerMenu');
    }

    public function getHomeUrl() {
        return $this->buildUrl('home');        
    }

    public function buildUrl($serviceId = null, $appId = null, $operationId = null, $data = null) {

        $params = array();

        if ($serviceId == 'index' || $serviceId == 'home') {
            return yii::app()->createUrl('site/index');
        }

        $bn = null;

        if ($serviceId != null) {
            //$serviceId = $service->getId();
            $serviceId = (($serviceId + 99) * 2 + 2) * 3;
            $bn = $serviceId;
        }

        if ($appId != null) {
            //$appId = $app->getId();
            $appId = (($appId + 99) * 3 + 2) * 2;
            $bn = $bn . "_" . $appId;
        }

        if ($operationId != null) {
            //$opId = $operation->getId();
            $opId = (($operationId + 99) * 2 + 2) * 3;
            $bn = $bn . "_" . $opId;
        }

        if ($bn != NULL)
            $params['bn'] = $bn;

        //rltp is roleType attached for service in left menu
        /*
          if (isset($_REQUEST['rtp'])) {
          $params['rtp'] = $_REQUEST['rtp'];
          //    unset($_REQUEST['rtp']);
          }
         * 
         */

        if ($data != null) {
            foreach ($data as $key => $value) {
                if ($key != 'bn')
                    $params[$key] = $value;
            }
        }

        $url = array('site/index');

        if (!empty($params)) {
            foreach ($params as $key => $value) {
                $url[$key] = $value;
            }
        }

        return $url;
    }

    public function deUrl() {

        if (isset($_GET['bn'])) {

            $bnString = $_GET['bn'];

            $t = explode("#", $bnString);

            $url = trim($t[0], "_");

            $s = explode("_", $url);

            $config = array();

            if (isset($s[0])) {
                $sId = intval($s[0]);
                $config['ServiceId'] = ($sId / 3 - 2) / 2 - 99;
            }

            if (isset($s[1])) {
                $aId = intval($s[1]);
                $config['AppId'] = ($aId / 2 - 2) / 3 - 99;
            }

            if (isset($s[2])) {
                $oId = intval($s[2]);
                $config['OperationId'] = ($oId / 3 - 2) / 2 - 99;
            }

            return $config;
        }
    }

    //put your code here
    public function getFormByMeta($formName, $parentScreen = null, $config = NULL) {

        $form = null;
        $formMeta = null;
        $formModel = null;

        if ($config != NULL) {
            if (isset($config['meta']))
                $formMeta = $config['meta'];

            if (isset($config['model']))
                $formModel = $config['model'];
        }

        if ($formMeta == NULL)
            $formMeta = $this->getFormMeta($formName . 'FormMeta');

        if ($formModel == NULL) {
            $modelName = $formName . 'FormModel';
            $formModel = new $modelName;
        }
        else
            $formModel = new $formModel;

        $formModel->setScenario($formName);

        $form = new CForm($formMeta, $formModel);

        return $form;
    }

    protected function getFormMeta($name) {

        if (function_exists('lcfirst'))
            $lname = lcfirst($name);
        else
            $lname = strtolower(substr($name, 0, 1)) . substr($name, 1);


        if (!isset($this->$lname)) {
            $meta = require(Yii::getPathOfAlias(Blyn::app()->getCurrentNode()->getUIManager()->getUINodeFilesPath('formPath') . ".meta." . $name) . '.php');
        }
        else
            $meta = $this->$lname;

        return $meta;
    }

    public function getScreen($name) {

        if (!$this instanceof BUINode) {
            $uiNode = Blyn::app()->getCurrentNode()->getUIManager();
        } else {
            $uiNode = $this;
        }
        return $uiNode->getScreen($name);
    }

    /**
     * 
     */
    public function getScreenFlow($name) {
        if (!$this instanceof BUINode) {
            $uiNode = Blyn::app()->getCurrentNode()->getUIManager();
        } else {
            $uiNode = $this;
        }
        return $uiNode->getScreenFlow($name);
    }

    public function gotoScreen($name, $data = array()) {
        $currentUINode = Blyn::app()->getCurrentNode()->getUIManager();

        $currentScreenFlow = $currentUINode->getCurrentScreenFlow();

        if ($currentScreenFlow instanceof BUIScreenFlow) {
            //$screen = $currentScreenFlow->getScreenByName($name);
            $fIndex = $currentScreenFlow->getIndexByName($name);
            $currentScreenFlow->setIndex($fIndex);
            $currentUINode->renderNode();
            yii::app()->end();
        }
        $screen = $this->getScreen($name);
        //refine on 3/3/2013
        $currentUINode->setCurrentScreen($screen);
        $currentUINode->renderNode($data);
        //  $screen->render($data);
    }

    public function gotoUINode($serviceId = NULL, $serviceAppId = NULL, $operationId = NULL, $data = array()) {
        //add by jianfeng in 3/3/2013
        Blyn::app()->setContext(array('serviceId' => $serviceId, 'serviceAppId' => $serviceAppId, 'operationId' => $operationId));
        $uiNode = Blyn::app()->getCurrentNode()->getUIManager();
        $uiNode->resetNode();
        if (isset($data['refreshLeftMenu']))
            Blyn::app()->getUIManager()->refreshLeftMenu();
        $uiNode->renderNode();
        /*
          $url = $this->buildUrl($serviceId, $serviceAppId, $operationId, $data);
          $currentScreen = Blyn::app()->getCurrentNode()->getUIManager()->getCurrentScreen();
          Blyn::app()->getTransitObj()->resetTransitVariable(BTransitObj::Scope_Application);

          if ($currentScreen instanceof BUIScreen)
          $currentScreen->beforeStartRender();
          $controller = yii::app()->getController();
          $controller->redirect($url);
         * 
         */
    }

    public function gotoScreenFlow($name, $data = array()) {
        $scnFlow = $this->getScreenFlow($name);
        $flowIndex = $scnFlow->getTransitVariable(BUIScreenFlow::TRANSITVARIABLE_SCREENFLOW_INDEX);
        if ($flowIndex == NULL) {
            $flowIndex = 0;
        }

        if (isset($_GET['screenFlowIndex'])) {
            $flowIndex = $_GET['screenFlowIndex'];
        }

        if (isset($data['index']))
            $flowIndex = $data['index'];

        $scnFlow->setIndex($flowIndex);

        // $scnFlow->render($data);
        //refine in 3/3/2013
        $currentUINode = Blyn::app()->getCurrentNode()->getUIManager();
        $currentUINode->setCurrentScreenFlow($scnFlow);
        $currentUINode->renderNode($data);
    }

    /**
     *
     * @param type $style
     * @return BMenuBootStrap 
     */
    protected function getMenuManager($style = null) {
        if ($style == NULL)
            $style = BUIApp::BOOTSTRAPSTYLE;

        if ($style == BUIApp::BOOTSTRAPSTYLE) {
            if ($this->bootStrapMenu == null) {
                $this->bootStrapMenu = new BMenuBootStrap ();
                $this->menuManager = $this->bootStrapMenu;
            }

            return $this->bootStrapMenu;
        }
    }

    public function getMenu($name, $style = null) {

        if ($style == NULL)
            $style = BUIApp::BOOTSTRAPSTYLE;

        $menuManager = Blyn::app()->getAppUI()->getMenuManager();

        $menu = $menuManager->getMenu($name);

        if ($menu == NULL) {
            $event = new CEvent($this);
            $this->onRegisterMenu($event);
            $menu = $menuManager->getMenu($name);
        }

        return $menu;
    }

    public function addMenuItem(&$menu, $menuItem, $style = NULL) {
        $menuManager = $this->getMenuManager($style);
        $menuManager->addMenuItem($menu, $menuItem);
    }

    public function addMenu($name, $menu, $style = NULL) {
        $menuManager = $this->getMenuManager($style);
        $menuManager->addMenu($name, $menu);
    }

    protected abstract function registerMenu($event);

    public function onRegisterMenu($event) {
        $this->raiseEvent('onRegisterMenu', $event);
    }

    public function renderView($view, $data = NULL, $uiNode = NULL) {

        $currentNode = Blyn::app()->getCurrentNode();
        $uiNode = $currentNode->getUIManager();

        if ($currentNode instanceof BOperation)
            $uiNode = Blyn::app()->getActiveServiceApp()->getUIManager();

        //    $viewPath = $uiNode->viewPath;

        if (!is_array($data))
            $data = array();

        if ($uiNode != NULL)
            $viewPath = $uiNode->viewPath;

        if (!is_dir(yii::getPathOfAlias($viewPath)))
            $viewPath = Blyn::app()->getAppUI()->viewPath;

        $viewFile = $viewPath . '.' . $view;

        if (!file_exists(yii::getPathOfAlias($viewFile) . '.php'))
            $viewFile = $viewPath = Blyn::app()->getAppUI()->viewPath . '.' . $view;
        else {
            $viewFile = $viewFile;
        }

        $controller = Yii::app()->getController();
        $controller->renderPartial($viewFile, $data);
//        $controller->renderPartial('blankLayout', array('view' => $view, 'data' => $data));
    }

    /*
      public function renderLayout($layout) {
      $this->renderView($layout->getLayoutView(), $layout->getLayoutData());
      }
     * 
     */

    public function addRenderView($name, $viewName, $viewData = NULL) {
        if ($viewData == NULL)
            $viewData = array('uiObj' => $this);
        if ($this->views == NULL)
            $this->views = array();
        $this->views[$name] = array('view' => $viewName, 'data' => $viewData);
    }

    public function setRenderView($name, $viewName, $viewData = NULL) {
        if (isset($this->views[$name]) && $viewName != NULL)
            $this->views[$name] = array('view' => $viewName, 'data' => $viewData);
    }

    public function removeRenderView($name) {
        if (isset($this->views[$name]))
            unset($this->views[$name]);
    }

    public function addAjaxRenderView($id, $viewName, $viewData = NULL) {
        $views = array();
        $ajaxLinkId = Blyn::app()->getCurrentNode()->getUIManager()->getCurrentScreen()->getId() . "_" . $id;
        if ($viewData == NULL)
            $viewData = array('uiObj' => $this);
        if ($this->ajaxViews == NULL)
            $this->ajaxViews = array();
        array_push($views, array('ajaxView' => $viewName, 'data' => $viewData));
        $this->ajaxViews[$ajaxLinkId] = $views;
    }

    public function getViews() {
        if ($this->views == NULL)
            $this->views = array();

        return $this->views;
    }

    public function getAjaxViews() {
        if ($this->ajaxViews == NULL)
            $this->ajaxViews = array();

        return $this->ajaxViews;
    }

    /**
     * 
     * @param type $id
     * @param type $name, name to show in link
     * @param type mix, format:string or array('ajaxView'=>'name of view','data'=>'data of view')
     * @param type $url
     * @param type $ajaxOption
     * @param type $htmlOption
     * @return type
     */
    public function buildAjaxLink($id, $name = null, $url = null, $ajaxViews = null, $ajaxOptions = array(), $htmlOptions = array()) {

        $ajaxLinkId = Blyn::app()->getCurrentNode()->getUIManager()->getCurrentScreen()->getId() . "_" . $id;

        if (yii::app()->getRequest()->isAjaxRequest) {
            $ajaxLinkId = 'j_' . $ajaxLinkId;
        }

        //prepare views
        $ajaxViewName = NULL;
        $aViews = array();

        if (is_string($ajaxViews)) {
            $ajaxViewName = $ajaxViews;
            array_push($aViews, array('ajaxView' => $ajaxViewName));
        }

        if (is_array($ajaxViews))
            $aViews = $ajaxViews;

        //if not specify any view for link, use startPage as view for show screen
        //meanwhile need to set up ajaxOption to update bilyn_start_page div
        if ($aViews == NULL) {
            array_push($aViews, array('ajaxView' => 'startPage'));
            $ajaxOptions['update'] = '#bilyn_start_page';
        }

        //add ajaxView into session variable, that will use before real render
        $ajaxRenderViews = Blyn::app()->getCurrentNode()->getUIManager()->getTransitVariable('bilyn_ajaxViews');

        if ($ajaxRenderViews == NULL)
            $ajaxRenderViews = array();

        $ajaxRenderViews[$ajaxLinkId] = $aViews;

        Blyn::app()->getCurrentNode()->getUIManager()->addTransitVariable('bilyn_ajaxViews', $ajaxRenderViews);
        Blyn::app()->getTransitObj()->uploadTransitVariable();

        //prepare url
        if ($url == NULL) {
            $url = Blyn::app()->getCurrentNode()->getUIManager()->getCurrentScreen()->getUrl();
        }
        $url['bilyn_ajaxLink'] = $ajaxLinkId;

        if ($name == NULL) {
            $name = $id;
        }

        $ajaxOptions['replace'] = TRUE;

        $request = yii::app()->getRequest();

        if ($request->isAjaxRequest) {
            if (!isset($ajaxOptions['type']))
                $ajaxOptions['type'] = 'POST';
            if (!isset($ajaxOptions['url']))
                $ajaxOptions['url'] = $url;
            /*
              if (isset($htmlOptions['submit'])) {
              $cs->registerCoreScript('yii');
              $request = Yii::app()->getRequest();
              if ($request->enableCsrfValidation && isset($htmlOptions['csrf']) && $htmlOptions['csrf'])
              $htmlOptions['params'][$request->csrfTokenName] = $request->getCsrfToken();
              if (isset($htmlOptions['params']))
              $params = CJavaScript::encode($htmlOptions['params']);
              else
              $params = '{}';
              if ($htmlOptions['submit'] !== '')
              $url = CJavaScript::quote(self::normalizeUrl($htmlOptions['submit']));
              else
              $url = '';
              $handler.="jQuery.yii.submitForm(this,'$url',$params);{$return};";
              }
             * 
             */
            //   if(isset($htmlOptions['submit'])){
            //      $ajaxOptions['data']='js:jQuery(this).parents("form").serialize()';
            //  }
            $ajaxScript = CHtml::ajax($ajaxOptions);
            $htmlOptions['onclick'] = $ajaxScript . 'return false;';
            $htmlOptions['id'] = blyn::app()->getCurrentNode()->getUIManager()->getUniqueControlId();
            $ajaxLink = CHtml::link($name, '#', $htmlOptions);
            //$ajaxlink = CHtml::ajaxLink($name, $url, $ajaxOptions, $htmlOptions);
            return $ajaxLink;
        }

        if (!isset($ajaxOptions['type']))
            $ajaxOptions['type'] = 'POST';

        $ajaxLink = CHtml::ajaxLink($name, $url, $ajaxOptions, $htmlOptions);

        return $ajaxLink;
    }

    /**
     * when create own ajax link by user sucess function, use this function to register views for ajaxLine
     * @param type $id
     * @param type $ajaxViews
     */
    public function registerAjaxLinkViews($id, $ajaxViews) {
        $this->buildAjaxLink($id, NULL, NULL, $ajaxViews);
        $ajaxLinkId = Blyn::app()->getCurrentNode()->getUIManager()->getCurrentScreen()->getId() . "_" . $id;
        return $ajaxLinkId;
    }

    public function getAjaxLinkId($id) {
        $ajaxLinkId = Blyn::app()->getCurrentNode()->getUIManager()->getCurrentScreen()->getId() . "_" . $id;
        return $ajaxLinkId;
    }

    public function isLinkClicked($id) {
        $id = Blyn::app()->getCurrentNode()->getUIManager()->getCurrentScreen()->getId() . "_" . $id;

        if (isset($_GET[$id]) || isset($_POST[$id]))
            return TRUE;

        return FALSE;
    }

    public function isAjaxLinkClicked($id) {
        $ajaxLinkId = Blyn::app()->getCurrentNode()->getUIManager()->getCurrentScreen()->getId() . "_" . $id;

        if (isset($_REQUEST['bilyn_ajaxLink']) &&
                ($_REQUEST['bilyn_ajaxLink'] === $ajaxLinkId || $_REQUEST['bilyn_ajaxLink'] === 'j_' . $ajaxLinkId))
            return TRUE;

        return FALSE;
    }

    public function buildAjaxScript($id, $ajaxViews = null, $url = null, $ajaxOption = NULL) {
        $ajaxLinkId = Blyn::app()->getCurrentNode()->getUIManager()->getCurrentScreen()->getId() . "_" . $id;

        //prepare views
        $ajaxViewName = NULL;
        $aViews = array();

        if (is_string($ajaxViews)) {
            $ajaxViewName = $ajaxViews;
            array_push($aViews, array('ajaxView' => $ajaxViewName));
        }

        if (is_array($ajaxViews))
            $aViews = $ajaxViews;

        //add ajaxView into session variable, that will use before real render
        $ajaxViews = Blyn::app()->getCurrentNode()->getUIManager()->getTransitVariable('bilyn_ajaxViews');

        if ($ajaxViews == NULL)
            $ajaxViews = array();

        $ajaxViews[$ajaxLinkId] = $aViews;
        Blyn::app()->getCurrentNode()->getUIManager()->addTransitVariable('bilyn_ajaxViews', $ajaxViews);
        Blyn::app()->getTransitObj()->uploadTransitVariable();

        //prepare url
        if ($url == NULL) {
            $url = Blyn::app()->getCurrentNode()->getUIManager()->getCurrentScreen()->getUrl();
        }
        $url['bilyn_ajaxLink'] = $ajaxLinkId;

        if (!is_array($ajaxOption))
            $ajaxOption = array();

        $ajaxOption['url'] = $url;

        return CHtml::ajax($ajaxOption);
    }

    public function buildLink($id, $label = NULL, $type = NULL, $url = NULL, $data = array(), $htmlOptions = array()) {

        $ajaxOptions = array();

        if ($type == "ajaxLink") {
            if ($data != NULL)
                $ajaxOptions['data'] = $data;
            $name = $label == NULL ? $id : $label;
            return $this->buildAjaxLink($id, $name, $url, NULL, $ajaxOptions, $htmlOptions);
        }

        if ($type == "ajaxButton") {
            if ($data != NULL)
                $ajaxOptions['data'] = $data;
            $name = $label == NULL ? $id : $label;
            $htmlOptions['class'] = isset($htmlOptions['class']) ? $htmlOptions['class'] . ' btn' : 'btn';
            return $this->buildAjaxLink($id, $name, $url, NULL, $ajaxOptions, $htmlOptions);
        }

        if ($type == "ajaxSubmitButton") {
            if ($data != NULL)
                $ajaxOptions['data'] = NULL;
            $name = $label == NULL ? $id : $label;
            $htmlOptions['class'] = isset($htmlOptions['class']) ? $htmlOptions['class'] . ' btn' : 'btn';
            //$htmlOptions['submit'] = 'true';
            return $this->buildAjaxLink($id, $name, $url, NULL, $ajaxOptions, $htmlOptions);
        }

        //$ajaxLinkId = Blyn::app()->getCurrentNode()->getUIManager()->getCurrentScreen()->getId() . "_" . $id;
        //prepare url
        if ($url == NULL) {
            $url = Blyn::app()->getCurrentNode()->getUIManager()->getCurrentScreen()->getUrl();
        }
        //$url[$ajaxLinkId] = '';

        $route = $url[0];
        unset($url[0]);

        $url = yii::app()->getController()->createUrl($route, $url);

        return $url;
    }

    public function createLink($id, $data = array()) {
        $linkType = self::LinkType_AjaxLink;
        if (isset($data['linkType'])) {
            $linkType = $data['linkType'];
        }
        $label = $id;
        if (isset($data['label'])) {
            $label = $data['label'];
        }
        $url = NULL;
        if (isset($data['url'])) {
            $url = $data['url'];
        }
        $ajaxData = NULL;
        if (isset($data['data'])) {
            $ajaxData = $data['data'];
        }
        $htmlOptions = array();
        if (isset($data['htmlOptions'])) {
            $htmlOptions = $data['htmlOptions'];
        }

        return $this->buildLink($id, $label, $linkType, $url, $ajaxData, $htmlOptions);
    }

    protected function getAjaxUrl($data = NULL) {

        if (isset($data['ajaxLink'])) {

            $ajaxLink = $data['ajaxLink'];
            //must unset ajaxLink here, otherwise maybe cause some error
            unset($data['ajaxLink']);
            $ajaxLinkId = isset($ajaxLink['id']) ? $ajaxLink['id'] : NULL;
            $ajaxLinkName = isset($ajaxLink['name']) ? $ajaxLink['name'] : NULL;
            $ajaxOptions = isset($ajaxLink['ajaxOptions']) ? $ajaxLink['ajaxOptions'] : NULL;
            $htmlOptions = isset($ajaxLink['htmlOptions']) ? $ajaxLink['htmlOptions'] : NULL;

            if ($ajaxLinkId == NULL)
                $ajaxLinkId = Blyn::app()->getUnicodeId();

            $url = $this->getUrl($data);

            return $this->buildAjaxLink($ajaxLinkId, $ajaxLinkName, $url, NULL, $ajaxOptions, $htmlOptions);
        };

        return NULL;
    }

    public function getUniqueControlId() {
        return 'bln' . $this->count++;
    }

}

?>
